# !/usr/bin/env python
# -*- coding: utf-8 -*-
"""
 -------------------------------------------------
    File Name:     base.py
    Description:   基础浏览器类
 -------------------------------------------------
 """
import re
from playwright.sync_api import sync_playwright, Page

from _hellchin_webrun.src.core.engine.models import ConfigModel
# from _hellchin_webrun.src.core.utils.logger.run_logger import TestLogger
from _hellchin_webrun.src.core.utils.chinese_alias import ChineseAliasMeta
from _hellchin_webrun.src.core.utils.logger.save_log import LoggerHandler


class BaseTest(metaclass=ChineseAliasMeta):

    def __init__(
            self,
            config: ConfigModel,
            browser=None,
            context=None,
            page: Page = None,
            log_obj=None
    ) -> None:
        """
        初始化
        :param config: 配置信息
        :param browser: 浏览器对象
        :param context: 上下文对象
        :param page: 页面对象
        """
        # super().__init__()
        self.config = config
        self.playwright = None
        self.pages = {}  # 页面列表

        # 实例化时，记录运行日志，随实例化消亡而重置
        self.log = log_obj or LoggerHandler()  # 测试套件是需要传入日志对象来记录日志。单独用例无需传入

        # 如果浏览器、上下文和页面都存在，则直接使用它们
        if all([browser, context, page]):
            self.browser = browser
            self.context = context
            self.page = page
            self.pages['default'] = self.page

    def __getattr__(self, item):
        """
        当前浏览器没创建时，自动创建浏览器, 访问不存在属性时，执行改方面

        :param item: 属性名称
        :return: 属性值
        """

        if item in ["browser", "context", "page"]:
            print(f"当前浏览器没有启动，{item}属性不存在，正在为你启动浏览器")
            self.open_browser(self.config.browser_type)
            return getattr(self, item)
        else:
            raise AttributeError(f"<UNK>{item}<UNK>属性不存在")

    def open_browser(self, browser_type="chromium"):
        """打开浏览器"""
        pass


class BrowserMixin(BaseTest):
    """浏览器操作相关方法"""

    def open_browser(self, browser_type="chromium"):
        """
        打开浏览器

        :param browser_type: 浏览器类型(chromium/firefox/webkit)
        :return:
        """

        # TestLogger.log_action("打开浏览器", browser_type, "start")
        # TestLogger.start.suit_log("打开浏览器", browser_type)

        try:
            self.__create_browser(browser_type or self.config.browser_type)
            self.pages['default'] = self.page
        except Exception as e:
            # TestLogger.fail.suit_log("打开浏览器", browser_type)
            self.log.error(f"打开浏览器: {browser_type}")
            print(e)
        else:
            # TestLogger.success.suit_log("打开浏览器", browser_type)
            self.log.info(f"打开浏览器: {browser_type}")

        # return self.page

    def __create_browser(self, browser_type):
        """创建浏览器"""
        # print("Creating new browser...")

        # 启动playwright，并获取浏览器实例
        self.playwright = sync_playwright().start()

        # 根据浏览器类型选择不同的浏览器
        if browser_type == "chromium":
            self.browser = self.playwright.chromium.launch(headless=not self.config.is_debug)
        elif browser_type == "firefox":
            self.browser = self.playwright.firefox.launch(headless=not self.config.is_debug)
        elif browser_type == "webkit":
            self.browser = self.playwright.webkit.launch(headless=not self.config.is_debug)
        else:
            raise ValueError(f"不支持的浏览器类型：{browser_type}")

        # 创建新的浏览器上下文,并创建新的页面
        self.context = self.browser.new_context()
        self.page = self.context.new_page()

        # return self.browser, self.context, self.page

    #
    # def open_browser(self, browser_type):
    #     """打开浏览器"""
    #     try:
    #         browser_type = browser_type or self.config.get("browser_type")
    #         self.browser, self.context, self.page = self.create_browser(
    #             browser_type,
    #             headless=self.config.get("is_debug")
    #         )
    #         self.pages['default'] = self.page
    #     except Exception as e:
    #         print("浏览器启动失败")
    #         print(e)
    #     else:
    #         print("浏览器启动成功")

    @staticmethod
    def create_browser(browser_type, headless):
        """创建浏览器实例"""
        pw = sync_playwright().start()
        browser_type = getattr(pw, browser_type)
        browser = browser_type.launch(headless=headless)
        context = browser.new_context()
        page = context.new_page()
        return browser, context, page

    def reset_browser_context(self):
        """重置浏览器运行环境"""
        self.page.close()
        self.context.close()
        self.context = self.browser.new_context()
        self.page = self.context.new_page()

    def close(self):
        """关闭浏览器"""
        self.page.close()
        self.context.close()
        self.browser.close()

    def open_new_page(self, tag):
        """
        打开新页面，为测试多页面的拓展操作

        :param tag: 页面标签
        :return: None
        """
        self.pages[tag] = self.context.new_page()
        print(f"已打开新页面，标签：{tag}")

    def find_page(self, tag='', index='', title='', url=''):
        """查找页面"""
        if tag:
            return self.pages[tag]
        elif index:
            return self.context.pages[int(index)]
        elif title:
            for page in self.context.pages:
                if page.title() == title:
                    return page
        elif url:
            for page in self.context.pages:
                if re.search(url, self.page.url):
                    return page
        return self.context.pages[-1]

    def switch_to_page(self, tag='', index='', title='', url=''):
        """切换到指定页面"""
        page = self.find_page(tag, index, title, url)
        self.page = page

    def close_page(self, tag='', index='', title='', url=''):
        """关闭指定页面"""
        page = self.find_page(tag, index, title, url)
        if page == self.page and len(self.context.pages) > 1:
            page.close()
            self.page = self.context.pages[0]
        else:
            page.close()
